package com.example.design_pattern.template;

abstract class Game {
    abstract void initialize();
    abstract void startPlay();
    abstract void endPlay();

    // 模板方法。
    public final void play() {
        // 初始化游戏
        initialize();

        // 开始游戏
        startPlay();

        // 结束游戏
        endPlay();
    }
}


// 板球。
// 板球游戏 extends 了 Game。那么，板球的类里面是有个不用显式写出来的play方法的。
class Cricket extends Game {
    @Override
    void initialize() {
        System.out.println("Cricket Game Initialized! Start playing.");
    }

    @Override
    void startPlay() {
        System.out.println("Cricket Game Started. Enjoy the game!");
    }

    @Override
    void endPlay() {
        System.out.println("Cricket Game Finished!");
    }
}


// 足球。
// 足球游戏 extends 了 Game。那么，足球的类里面是有个不用显式写出来的play方法的。
class Football extends Game {
    @Override
    void initialize() {
        System.out.println("Football Game Initialized! Start playing.");
    }

    @Override
    void startPlay() {
        System.out.println("Football Game Started. Enjoy the game!");
    }

    @Override
    void endPlay() {
        System.out.println("Football Game Finished!");
    }
}

public class TemplateTest {
    public static void main(String[] args) {
        Game game = new Cricket();
        // 板球的play到时候调用的就是板球自己实现的initialize、startPlay、endPlay方法。
        game.play();

        System.out.println();

        game = new Football();
        // 足球的play到时候调用的就是板球自己实现的initialize、startPlay、endPlay方法。
        game.play();
    }
}


//备注：
// 在上面的示例中，Game 类是一个抽象类，定义了一个模板方法 play()，该方法规定了游戏的执行流程，包括初始化、开始游戏和结束游戏的步骤。
// 具体的游戏类 Cricket 和 Football 继承自 Game 类并实现了抽象方法，定义了各自游戏的初始化、开始和结束方法。
// 在 TemplatePatternDemo 类中，创建了具体的游戏对象并调用 play() 方法执行游戏。

// 模板设计模式，一般用于什么场景
// 模板设计模式通常用于以下场景：
//1. **固定流程的算法或操作**：当一个算法或操作有固定的执行步骤，但是每个步骤的具体实现可能不同，可以使用模板设计模式。这样可以将固定的执行流程封装在模板方法中，而具体的步骤实现交给子类去完成。
//2. **避免代码重复**：模板方法中的固定流程可以避免在每个子类中重复编写相同的代码，提高了代码的重用性。
//3. **定义框架**：在框架设计中，模板方法模式常用于定义框架的核心算法或逻辑，而具体的实现由框架的用户根据需求来提供。
//4. **简化复杂问题**：将一个复杂的问题分解为几个简单的步骤，并且每个步骤的实现可以独立变化，使用模板方法可以简化问题的处理。
//总之，模板设计模式适用于任何需要定义固定流程的场景，其中每个步骤的具体实现可能会变化的情况。

// Spring提供了JdbcTemplate等模板类简化了对数据库访问的操作，遵循了模板模式的设计思想。
